import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { Expense, ExpenseCategory } from '../types';
import { toast } from 'sonner';

interface ExpenseContextType {
  expenses: Expense[];
  addExpense: (expense: Omit<Expense, 'id'>) => void;
  deleteExpense: (id: string) => void;
  updateExpense: (id: string, updatedExpense: Partial<Omit<Expense, 'id'>>) => void;
  getExpensesByPeriod: (startDate: string, endDate: string) => Expense[];
  getTotalExpense: () => number;
  getExpensesByCategory: () => Record<string, number>;
}

const ExpenseContext = createContext<ExpenseContextType | undefined>(undefined);

export const ExpenseProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  // 从localStorage加载数据，添加更健壮的错误处理
  const [expenses, setExpenses] = useState<Expense[]>(() => {
    try {
      // 从localStorage加载数据
      const savedExpenses = localStorage.getItem('expenses');
      if (savedExpenses) {
        const parsed = JSON.parse(savedExpenses);
        // 验证数据格式是否正确
        if (Array.isArray(parsed)) {
          // 过滤掉格式不正确的记录
          const validExpenses = parsed.filter(item => 
            item && 
            typeof item.amount === 'number' && 
            typeof item.category === 'string' && 
            typeof item.description === 'string' && 
            typeof item.date === 'string' && 
            typeof item.id === 'string'
          );
          return validExpenses;
        }
      }
    } catch (error) {
      console.error('Failed to parse expenses from localStorage', error);
      toast('从本地存储加载数据时出错，已重置为空列表');
    }
    
    // 如果没有有效数据，返回空数组
    return [];
  });

  // 当expenses变化时，保存到localStorage
  useEffect(() => {
    try {
      localStorage.setItem('expenses', JSON.stringify(expenses));
    } catch (error) {
      console.error('Failed to save expenses to localStorage', error);
      toast('保存数据到本地存储时出错');
    }
  }, [expenses]);

  // 添加新的消费记录 - 增强版，确保数据有效性
  const addExpense = (expenseData: Omit<Expense, 'id'>) => {
    try {
      // 验证数据有效性
      if (typeof expenseData.amount !== 'number' || 
          typeof expenseData.category !== 'string' ||
          typeof expenseData.description !== 'string' ||
          typeof expenseData.date !== 'string') {
        throw new Error('Invalid expense data');
      }
      
      const newExpense: Expense = {
        ...expenseData,
        id: Date.now().toString() // 使用时间戳作为唯一ID
      };
      
      // 使用函数式更新确保获取最新状态
      setExpenses(prevExpenses => {
        // 创建一个新的数组引用以确保组件重新渲染
        const updatedExpenses = [newExpense, ...prevExpenses];
        return updatedExpenses;
      });
      
      console.log('Expense added successfully:', newExpense);
    } catch (error) {
      console.error('Failed to add expense:', error);
      toast('添加消费记录时出错');
    }
  };

  // 删除消费记录
  const deleteExpense = (id: string) => {
    setExpenses(prev => prev.filter(expense => expense.id !== id));
  };

  // 更新消费记录
  const updateExpense = (id: string, updatedExpense: Partial<Omit<Expense, 'id'>>) => {
    setExpenses(prev => 
      prev.map(expense => 
        expense.id === id ? { ...expense, ...updatedExpense } : expense
      )
    );
  };

  // 获取指定时间段内的消费记录
  const getExpensesByPeriod = (startDate: string, endDate: string) => {
    return expenses.filter(expense => {
      const expenseDate = new Date(expense.date);
      return expenseDate >= new Date(startDate) && expenseDate <= new Date(endDate);
    });
  };

  // 获取总消费金额
  const getTotalExpense = (): number => {
    return expenses.reduce((total, expense) => total + expense.amount, 0);
  };

  // 按类别获取消费金额
  const getExpensesByCategory = (): Record<string, number> => {
    return expenses.reduce((acc, expense) => {
      acc[expense.category] = (acc[expense.category] || 0) + expense.amount;
      return acc;
    }, {} as Record<string, number>);
  };

  const value: ExpenseContextType = {
    expenses,
    addExpense,
    deleteExpense,
    updateExpense,
    getExpensesByPeriod,
    getTotalExpense,
    getExpensesByCategory
  };

  return <ExpenseContext.Provider value={value}>{children}</ExpenseContext.Provider>;
};

// 自定义Hook，方便使用Context
export const useExpenses = () => {
  const context = useContext(ExpenseContext);
  if (context === undefined) {
    throw new Error('useExpenses must be used within an ExpenseProvider');
  }
  return context;
};